/**
 * 
 */
package security;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import bean.ParamBean;
import bean.UserProfile;

import service.Service;

/**
 * Service Authorization Checker.
 * 
 * @author chuxiaoyuan
 *
 */
public class ServiceAuthChecker implements IAuthChecker {

	/**
	 * Constructor.
	 */
	public ServiceAuthChecker(
			Service service, Method serviceHandler) {
		this(service, serviceHandler, null);
	}
	
	/**
	 * Constructor.
	 */
	public ServiceAuthChecker(
			Service service, Method serviceHandler, HttpServletRequest request) {
		
		this.setService(service);
		this.setServiceHandler(serviceHandler);
		this.setRequest(request);
	}
	
	/**
	 * The service information.
	 */
	private Service service;
	
	/**
	 * The service handler.
	 */
	private Method serviceHandler;

	/**
	 * The servlet request.
	 */
	private HttpServletRequest request;
	
	/**
	 * @return the service
	 */
	public Service getService() {
		return service;
	}

	/**
	 * @param service the service to set
	 */
	public void setService(Service service) {
		this.service = service;
	}

	/**
	 * @return the serviceHandler
	 */
	public Method getServiceHandler() {
		return serviceHandler;
	}

	/**
	 * @param serviceHandler the serviceHandler to set
	 */
	public void setServiceHandler(Method serviceHandler) {
		this.serviceHandler = serviceHandler;
	}

	/**
	 * @return the request
	 */
	public HttpServletRequest getRequest() {
		return request;
	}

	/**
	 * @param request the request to set
	 */
	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}
	
	/* (non-Javadoc)
	 * @see security.IAuthChecker#hasPermission(security.SecurityRole)
	 */
	@Override
	public boolean hasPermission() {
		
		// Validate service
		Service service = this.getService();
		Method handler = this.getServiceHandler();
		if (service == null || handler == null) {
			return false;
		}
		
		// Test against roles
		SecurityRole role = service.security();
		if (SecurityRole.None.equals(role)) {
			
			// Bypass security check.
			return true;
		}
		
		// Validate user credential
		HttpServletRequest request = this.getRequest();
		if (request == null) {
			return false;
		}
		HttpSession session = request.getSession(false);
		if (session == null) {
			// No valid session
			return false;
		}
		
		// Validate parameter bean
		ParamBean param = ParamBean.getParamBean(session);
		if (param == null || param.getUserProfile() == null) {
			return false;
		}
		
		if (SecurityRole.All.equals(role)) {
			// Only check if it is valid user.
			return true;
		}
		
		// Check roles
		UserProfile profile = param.getUserProfile();
		if (SecurityRole.Customer.equals(role)) {
			
			return profile.isCustomer();
		}
		if (SecurityRole.Admin.equals(role)) {
			
			return profile.isAdmin();
		}
		
		// Fail safe default
		return false;
	}


}
